package com.flyco.modules.stm.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyco.common.api.vo.Result;
import com.flyco.common.aspect.annotation.AutoLog;
import com.flyco.common.system.query.QueryGenerator;
import com.flyco.common.system.vo.LoginUser;
import com.flyco.common.util.DateUtils;
import com.flyco.common.util.oConvertUtils;
import com.flyco.modules.pms.entity.PmsProduct;
import com.flyco.modules.pms.service.IPmsProductService;
import com.flyco.modules.stm.entity.*;
import com.flyco.modules.stm.model.StmReplenishmentItemModel;
import com.flyco.modules.stm.service.*;
import com.flyco.modules.stm.vo.StmPrintVO;
import com.flyco.modules.stm.vo.StmReplenishmentItemPage;
import com.flyco.modules.stm.vo.StmReplenishmentPage;
import com.flyco.modules.stm.vo.StmTransferVO;
import com.flyco.modules.system.service.ISysDictService;
import com.flyco.poi.excel.ExcelImportUtil;
import com.flyco.poi.excel.def.NormalExcelConstants;
import com.flyco.poi.excel.entity.ExportParams;
import com.flyco.poi.excel.entity.ImportParams;
import com.flyco.poi.excel.view.EntityExcelView;
import com.google.common.base.Joiner;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @Description: 门店要货单
 * @Author: flyco
 * @Date: 2020-11-23
 * @Version: V1.0
 */
@Api(tags = "门店要货单")
@RestController
@RequestMapping("/f/stm/stmReplenishment")
@Slf4j
public class StmReplenishmentController {
    @Autowired
    private IStmReplenishmentService stmReplenishmentService;
    @Autowired
    private IStmReplenishmentItemService stmReplenishmentItemService;
    @Autowired
    private IStmStoreInfoService stmStoreInfoService;
    @Autowired
    private IPmsProductService pmsProductService;
    @Autowired
    private ISysDictService dictService;
    @Autowired
    private IStmStockInoutService stmStockInoutService;
    @Autowired
    private IStmTransferService stmTransferService;
    @Autowired
    private IStmReplenishmentTransferRelationService stmReplenishmentTransferRelationService;

    /**
     * 分页列表查询
     *
     * @param stmReplenishment
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "门店要货单-分页列表查询")
    @ApiOperation(value = "门店要货单-分页列表查询", notes = "门店要货单-分页列表查询")
    @GetMapping(value = "/list")
    public Result<?> queryPageList(StmReplenishment stmReplenishment,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<StmReplenishment> queryWrapper = QueryGenerator.initQueryWrapper(stmReplenishment, req.getParameterMap());
        Page<StmReplenishment> page = new Page<StmReplenishment>(pageNo, pageSize);
        queryWrapper.eq("version",1);
        IPage<StmReplenishment> pageList = stmReplenishmentService.page(page, queryWrapper);
        if (pageList.getTotal() > 0) {
            List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
            Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));
            pageList.getRecords().forEach(replenishment -> {
                if (oConvertUtils.isNotEmpty(replenishment.getStoreId())) {
                    if (storeInfoMaps.containsKey(replenishment.getStoreId())) {
                        replenishment.setStoreId_dictText(storeInfoMaps.get(replenishment.getStoreId()));
                    } else {
                        if (Objects.equals(0L , replenishment.getStoreId() )) {
                            replenishment.setStoreId_dictText("线上商城");
                        }
                    }
                }
            });
        }
        return Result.ok(pageList);
    }

    /**
     * 添加
     *
     * @param stmReplenishmentPage
     * @return
     */
    @AutoLog(value = "门店要货单-添加")
    @ApiOperation(value = "门店要货单-添加", notes = "门店要货单-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody StmReplenishmentPage stmReplenishmentPage) {
        StmReplenishment stmReplenishment = new StmReplenishment();
        BeanUtils.copyProperties(stmReplenishmentPage, stmReplenishment);
        stmReplenishmentService.save(stmReplenishment);
        return Result.ok("添加成功！");
    }

    /**
     * 编辑
     *
     * @param stmReplenishmentPage
     * @return
     */
    @AutoLog(value = "门店要货单-编辑")
    @ApiOperation(value = "门店要货单-", notes = "门店要货单-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody StmReplenishmentPage stmReplenishmentPage) {
        StmReplenishment stmReplenishment = new StmReplenishment();
        BeanUtils.copyProperties(stmReplenishmentPage, stmReplenishment);
        stmReplenishmentService.updateById(stmReplenishment);
        return Result.ok("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "门店要货单-通过id删除")
    @ApiOperation(value = "门店要货单-通过id删除", notes = "门店要货单-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) Long id) {
        stmReplenishmentService.delMain(id);
        return Result.ok("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "门店要货单-批量删除")
    @ApiOperation(value = "门店要货单-批量删除", notes = "门店要货单-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.stmReplenishmentService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.ok("批量删除成功！");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "门店要货单-通过id查询")
    @ApiOperation(value = "门店要货单-通过id查询", notes = "门店要货单-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) Long id) {
        StmReplenishment stmReplenishment = stmReplenishmentService.getById(id);
        return Result.ok(stmReplenishment);
    }

    /**
     * 生成进出库单
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "生成进出库单")
    @PostMapping(value = "/generateInout")
    public Result<?> generateInout(@RequestBody String[] ids) {
        LambdaQueryWrapper<StmReplenishment> query = new LambdaQueryWrapper<>();
        query.in(StmReplenishment::getId, ids);
        List<StmReplenishment> replenishments = stmReplenishmentService.list(query);
        List<StmReplenishment> errList = replenishments.stream().filter(r -> Arrays.asList(0, 4).contains(r.getStatus())).collect(Collectors.toList());
        if (oConvertUtils.isNotEmpty(errList) && errList.size() > 0) {
            return Result.error("选中的补货单中存在未提交或已取消的单据！");
        }
        StmReplenishment maxReplenishment = replenishments.stream().max(Comparator.comparing(StmReplenishment::getCreateTime)).get();
        Date createTime = maxReplenishment.getCreateTime();
        List<StmReplenishment> sList = replenishments.stream().filter(r -> oConvertUtils.isNotEmpty(r.getExecTime())).collect(Collectors.toList());
        if (oConvertUtils.isNotEmpty(sList) && sList.size() > 0) {
            StmReplenishment maxExecReplenishment = sList.stream().max(Comparator.comparing(StmReplenishment::getExecTime)).get();
            if (oConvertUtils.isNotEmpty(maxExecReplenishment) && oConvertUtils.isNotEmpty(maxExecReplenishment.getExecTime()) ) {
                createTime = maxExecReplenishment.getExecTime();
            }
        }
        List<Long> replenishmentIdList = replenishments.stream().map(StmReplenishment::getId).collect(Collectors.toList());
        List<StmPrintVO> printVOList = stmReplenishmentItemService.selectByIds(replenishmentIdList,createTime);
        Map<Long, BigDecimal> printVOMap = printVOList.stream().filter(x -> oConvertUtils.isNotEmpty(x.getCostPrice())).collect(Collectors.toMap(StmPrintVO::getProductId, StmPrintVO::getCostPrice, (key1, key2) -> key2));
        StmStockInout stockInout = new StmStockInout();
        stockInout.setStoreId(0L);
        stockInout.setType("STOCK_IN");
        stockInout.setStatus(0);
        stockInout.setSourceType("RECEIPT_TYPE_REPLENISHMENT");
        stockInout.setSourceIds(Joiner.on(",").skipNulls().join(ids));

        LambdaQueryWrapper<StmReplenishmentItem> itemQuery = new LambdaQueryWrapper<>();
        itemQuery.in(StmReplenishmentItem::getReplenishmentId, ids);
        List<StmReplenishmentItem> items = stmReplenishmentItemService.list(itemQuery);

        List<StmStockInoutItem> inoutItems = new ArrayList<>();

        Map<String, List<StmReplenishmentItem>> itemMap = items.stream().collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
        itemMap.entrySet().forEach(entry -> {
            List<StmReplenishmentItem> replenishmentItems = entry.getValue();
            StmReplenishmentItem replenishmentItem = replenishmentItems.get(0);
            StmStockInoutItem inoutItem = new StmStockInoutItem();
            inoutItem.setProductId(replenishmentItem.getProductId());
            inoutItem.setProductSn(replenishmentItem.getProductSn());
            inoutItem.setStockType(replenishmentItem.getStockType());
            inoutItems.add(inoutItem);
        });
        stmStockInoutService.saveMain(stockInout,inoutItems);

        return Result.ok("生成成功！");

    }

    /**
     * 生成调拨单
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "生成调拨单")
    @PostMapping(value = "/generateTransfer")
    public Result<?> generateTransfer(@RequestBody String[] ids) {
        LambdaQueryWrapper<StmReplenishment> query = new LambdaQueryWrapper<>();
        query.in(StmReplenishment::getId, ids);
        List<StmReplenishment> replenishments = stmReplenishmentService.list(query);
        List<StmReplenishment> errList = replenishments.stream().filter(r -> 3!=r.getStatus() || 1==r.getTransferFlag()).collect(Collectors.toList());
        if (oConvertUtils.isNotEmpty(errList) && errList.size() > 0) {
            return Result.error("选中的补货单只能是已审核且未生成调拨单的单据！");
        }
        Map<Long,StmTransferVO> voMap = new HashMap<>();
        Map<Long,List<StmReplenishmentTransferRelation>> relationMap = new HashMap<>();
        //--------------构建调拨单主表-----------------------------------------
        Map<Long, List<StmReplenishment>> replenishmentMap = replenishments.stream().collect(Collectors.groupingBy(StmReplenishment::getStoreId));
        replenishmentMap.entrySet().forEach(entry -> {
            List<StmReplenishment> replenishmentList = entry.getValue();
            List<StmReplenishmentTransferRelation> relationList = new ArrayList<>();
            replenishmentList.forEach(r->{
                StmReplenishmentTransferRelation transferRelation = new StmReplenishmentTransferRelation();
                transferRelation.setReplenishmentId(r.getId());
                transferRelation.setCancelFlag(0);
                relationList.add(transferRelation);
            });
            relationMap.put(entry.getKey(),relationList);
            StmReplenishment replenishment = replenishmentList.get(0);
            StmTransfer transfer = new StmTransfer();
            transfer.setInStoreId(replenishment.getStoreId());
            transfer.setCreateSalesId(replenishment.getCreateSalesId());
            transfer.setConfirmInSalesId(replenishment.getConfirmSalesId());
            transfer.setOutStoreId(0L);
            //总仓到门店的调拨单直接是已审核
            transfer.setStatus(3);
            StmTransferVO vo = new StmTransferVO();
            vo.setTransfer(transfer);
            voMap.put(entry.getKey(),vo);
        });
        //--------------构建调拨单主表结束-----------------------------------------
        //--------------构建调拨单明细--------------------------------------------
        Map<Long, List<Long>> storeMap =  replenishments.stream().collect(Collectors.groupingBy(StmReplenishment::getStoreId, Collectors.mapping(StmReplenishment::getId, Collectors.toList())));
        storeMap.entrySet().forEach(entry -> {
            List<Long> replenishmentIds = entry.getValue();
            LambdaQueryWrapper<StmReplenishmentItem> itemQuery = new LambdaQueryWrapper<>();
            itemQuery.in(StmReplenishmentItem::getReplenishmentId, replenishmentIds);
            List<StmReplenishmentItem> items = stmReplenishmentItemService.list(itemQuery);
            Map<String, List<StmReplenishmentItem>> itemMap = items.stream().collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
            List<StmTransferItem> transferItems = new ArrayList<>();
            AtomicReference<Integer> sumProductQty = new AtomicReference<>(0);
            itemMap.entrySet().forEach(itemEntry -> {
                List<StmReplenishmentItem> replenishmentItems = itemEntry.getValue();
                StmReplenishmentItem replenishmentItem = replenishmentItems.get(0);
                StmTransferItem transferItem = new StmTransferItem();
                transferItem.setProductId(replenishmentItem.getProductId());
                transferItem.setProductSn(replenishmentItem.getProductSn());
                transferItem.setStockType(replenishmentItem.getStockType());
                transferItem.setProductQty(replenishmentItems.stream().mapToInt(p -> p.getProductQty()).sum());
                sumProductQty.updateAndGet(v -> v + transferItem.getProductQty());
                transferItems.add(transferItem);
            });
            StmTransferVO vo = voMap.get(entry.getKey());
            vo.setTransferItems(transferItems);
            vo.getTransfer().setNote("共" + sumProductQty.get() + "件");
            voMap.put(entry.getKey(),vo);
        });
        //--------------构建调拨单明细结束------------------------------------------
        voMap.entrySet().forEach(entry -> {
            StmTransferVO vo = entry.getValue();
            stmTransferService.saveMain(vo.getTransfer(),vo.getTransferItems());
            relationMap.get(entry.getKey()).forEach(relation->{
                relation.setTransferId(vo.getTransfer().getId());
            });
            stmReplenishmentTransferRelationService.saveBatch( relationMap.get(entry.getKey()));
        });
        //--------------更新要货单状态------------------------------------------
        StmReplenishment updateReplenishment = new StmReplenishment();
        //updateReplenishment.setStatus(7);
        updateReplenishment.setTransferFlag(1);
        stmReplenishmentService.update(updateReplenishment,query);
        return Result.ok("生成成功！");
    }

    @AutoLog(value = "审批要货单")
    @PostMapping(value = "/apply")
    public Result<?> apply(@RequestBody ReplenishmentApplyDTO replenishmentApplyDTO) {
        if(replenishmentApplyDTO.getStatus()==null || replenishmentApplyDTO.getIds()==null){
            return Result.error("参数不能为空");
        }

        return stmReplenishmentService.apply(replenishmentApplyDTO.getStatus(), Arrays.asList(replenishmentApplyDTO.getIds()));
    }

    /**
     * 撤销要货单(准备废弃)
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "撤销要货单")
    @PostMapping(value = "/rollbackByIds")
    public Result<?> rollbackByIds(@RequestBody String[] ids) {
        log.info("ids:" + ids.toString());
        LambdaQueryWrapper<StmReplenishment> query = new LambdaQueryWrapper<>();
        query.in(StmReplenishment::getId, ids);
        List<StmReplenishment> replenishments = stmReplenishmentService.list(query);
        List<StmReplenishment> errList = replenishments.stream().filter(r -> !Arrays.asList(3).contains(r.getStatus()) || 1==r.getTransferFlag()).collect(Collectors.toList());
        if (oConvertUtils.isNotEmpty(errList) && errList.size() > 0) {
            return Result.error("只有已审核且未生成调拨单的要货单才可以撤销！");
        }
        LambdaUpdateWrapper<StmReplenishment> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(StmReplenishment::getId, ids);
        updateWrapper.set(StmReplenishment::getStatus,0);
        stmReplenishmentService.update(updateWrapper);
        return Result.ok("撤销成功！");
    }


    //===========================以下是子表信息操作相关API====================================

    /**
     * 通过主表id查询门店要货明细
     *
     * @param stmReplenishmentItem
     * @return
     */
    @AutoLog(value = "门店要货明细-通过主表id查询")
    @ApiOperation(value = "门店要货明细-通过主表id查询", notes = "门店要货明细-通过主表id查询")
    @GetMapping(value = "/listStmReplenishmentItemByMainId")
    public Result<?> listStmReplenishmentItemByMainId(StmReplenishmentItem stmReplenishmentItem,
                                                      @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                      HttpServletRequest req) {
        //if (stmReplenishmentItem.getReplenishmentId() != null) {
        QueryWrapper<StmReplenishmentItem> queryWrapper = QueryGenerator.initQueryWrapper(stmReplenishmentItem, req.getParameterMap());
        Page<StmReplenishmentItemPage> page = new Page<StmReplenishmentItemPage>(pageNo, pageSize);
        IPage<StmReplenishmentItemPage> pageList = stmReplenishmentItemService.getReplenishmentItemPage(page, queryWrapper);
        if (pageList.getTotal() > 0) {
            List<StmReplenishmentItem> items = stmReplenishmentItemService.list(queryWrapper);

            List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
            Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));

            Set<Long> replenishmentIds = items.stream().map(r -> r.getReplenishmentId()).collect(Collectors.toSet());
            LambdaQueryWrapper<StmReplenishment> replenishmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
            replenishmentLambdaQueryWrapper.in(StmReplenishment::getId, replenishmentIds);
            List<StmReplenishment> replenishments = stmReplenishmentService.list(replenishmentLambdaQueryWrapper);
            //要货单ID与门店名称对应关系
            Map<Long, String> res = new HashMap<Long, String>();
            replenishments.forEach(r -> {
                if (storeInfoMaps.containsKey(r.getStoreId())) {
                    res.put(r.getId(), storeInfoMaps.get(r.getStoreId()));
                }
            });
            LambdaQueryWrapper<PmsProduct> query = new LambdaQueryWrapper<>();
            query.select(PmsProduct::getId, PmsProduct::getName, PmsProduct::getProductSn);
            List<PmsProduct> products = pmsProductService.list(query);
            Map<Long, String> productMap = products.stream().collect(Collectors.toMap(PmsProduct::getId, PmsProduct::getName, (key1, key2) -> key2));

            items.forEach(i -> {
                if (res.containsKey(i.getReplenishmentId())) {
                    i.setStoreId_dictText(res.get(i.getReplenishmentId()));
                }
                if (productMap.containsKey(i.getProductId())) {
                    i.setProductId_dictText(productMap.get(i.getProductId()));
                }
                i.setStockType_dictText(dictService.queryDictTextByKey("stock_type_replenishment", i.getStockType()));
                i.setItemKey(i.getId().toString());
            });
            Map<String, List<StmReplenishmentItem>> itemMap = items.stream().collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
            pageList.getRecords().forEach(replenishmentItem -> {
                String key = pageKey(replenishmentItem);
                replenishmentItem.setItemKey(key);
                if (itemMap.containsKey(key)) {
                    replenishmentItem.setChildren(itemMap.get(key));
                }

            });
        }
        return Result.ok(pageList);
        //} else {
        //    return Result.error("请选择一条记录");
        //}
    }

    private static String fetchGroupKey(StmReplenishmentItem item) {
        return item.getProductId() + "#" + item.getProductSn() + "#" + item.getStockType();
    }

    private static String pageKey(StmReplenishmentItemPage item) {
        return item.getProductId() + "#" + item.getProductSn() + "#" + item.getStockType();
    }


    /**
     * 通过id查询
     *
     * @param mainId
     * @return
     */
    @AutoLog(value = "门店要货明细-通过MainId查询")
    @ApiOperation(value = "门店要货明细-通过MainId查询", notes = "门店要货明细-通过MainId查询")
    @GetMapping(value = "/queryReplenishmentItemByMainId")
    public Result<?> queryReplenishmentItemByMainIds(@RequestParam(name = "mainId", required = true) String mainId) {
        log.info("mainIds：" + mainId);
        LambdaQueryWrapper<StmReplenishment> replenishmentLambdaQueryWrapper = new LambdaQueryWrapper<>();
        replenishmentLambdaQueryWrapper.in(StmReplenishment::getId, Arrays.asList(mainId.split(",")).stream().map(s -> Long.valueOf(s.toString())).collect(Collectors.toList()));
        List<StmReplenishment> replenishments = stmReplenishmentService.list(replenishmentLambdaQueryWrapper);
        StmReplenishment maxReplenishment = replenishments.stream().max(Comparator.comparing(StmReplenishment::getCreateTime)).get();
        Date createTime = maxReplenishment.getCreateTime();
        List<StmReplenishment> sList = replenishments.stream().filter(r -> oConvertUtils.isNotEmpty(r.getExecTime())).collect(Collectors.toList());
        if (oConvertUtils.isNotEmpty(sList) && sList.size() > 0) {
            StmReplenishment maxExecReplenishment = sList.stream().max(Comparator.comparing(StmReplenishment::getExecTime)).get();
            if (oConvertUtils.isNotEmpty(maxExecReplenishment) && oConvertUtils.isNotEmpty(maxExecReplenishment.getExecTime()) ) {
                createTime = maxExecReplenishment.getExecTime();
            }
        }
        Set<Long> storeIds = replenishments.stream().map(r -> r.getStoreId()).collect(Collectors.toSet());
        List<StmStoreInfo> storeInfos = stmStoreInfoService.list();
        Map<Long, String> storeInfoMaps = storeInfos.stream().collect(Collectors.toMap(StmStoreInfo::getStoreId, StmStoreInfo::getName, (key1, key2) -> key2));
        Map<String,Object> map = new HashMap<>();
        if (storeIds.size() == 1) {
            map.put("applyName",replenishments.get(0).getCreateSales());
            map.put("applyStore",storeInfoMaps.get(replenishments.get(0).getStoreId()));
            map.put("applyTime",DateUtils.formatDate(replenishments.get(0).getCreateTime()));
        } else {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            map.put("applyName",sysUser.getRealname());
            if (storeInfoMaps.containsKey(0L)) {
                map.put("applyStore",storeInfoMaps.get(0L));
            } else {
                map.put("applyStore","总仓");
            }
            map.put("applyTime", DateUtils.formatDate());
        }
        List<StmPrintVO> printVOList = stmReplenishmentItemService.selectByIds(Arrays.asList(mainId.split(",")).stream().map(s -> Long.valueOf(s.toString())).collect(Collectors.toList()),createTime);
        map.put("printList", printVOList);
        return Result.ok(map);
    }

    /**
     * 添加门店要货明细
     *
     * @param stmReplenishmentItemModel
     * @return
     */
    @AutoLog(value = "门店要货明细-添加")
    @ApiOperation(value = "门店要货明细-添加", notes = "门店要货明细-添加")
    @PostMapping(value = "/addStmReplenishmentItem")
    public Result<?> addStmReplenishmentItem(@RequestBody StmReplenishmentItemModel stmReplenishmentItemModel) {
        if (oConvertUtils.isEmpty(stmReplenishmentItemModel) || oConvertUtils.isEmpty(stmReplenishmentItemModel.getReplenishmentId()) || oConvertUtils.isEmpty(stmReplenishmentItemModel.getDetailList())) {
            return Result.error("数据为空！");
        }
        StmReplenishment stmReplenishment = stmReplenishmentService.getById(stmReplenishmentItemModel.getReplenishmentId());
        if (oConvertUtils.isEmpty(stmReplenishment)) {
            return Result.error("要货单主表记录为空，请检查后重试！");
        }
        if (stmReplenishment.getStatus() > 3) {
            return Result.error("要货单状态已不可再增加商品！");
        }
        List<String> productSns = stmReplenishmentItemModel.getDetailList().stream().map(StmReplenishmentItem::getProductSn).collect(Collectors.toList());
        long count = productSns.stream().distinct().count();
        if (count < productSns.size()) {
            return Result.error("新添加的记录中存在重复数据，请重核对后重试！");
        }
        LambdaQueryWrapper<PmsProduct> query = new LambdaQueryWrapper<>();
        query.in(PmsProduct::getProductSn, productSns);
        List<PmsProduct> products = pmsProductService.list(query);
        Map<String, Long> productMaps = products.stream().collect(Collectors.toMap(PmsProduct::getProductSn, PmsProduct::getId, (key1, key2) -> key2));
        List<StmReplenishmentItem> stmReplenishmentItemList = stmReplenishmentItemService.selectByMainId(stmReplenishmentItemModel.getReplenishmentId());
        if (oConvertUtils.isNotEmpty(stmReplenishmentItemList) && stmReplenishmentItemList.size() > 0) {
            List<Long> productIds = products.stream().map(PmsProduct::getId).collect(Collectors.toList());
            List<Long> dbItemProductIds = stmReplenishmentItemList.stream().map(StmReplenishmentItem::getProductId).collect(Collectors.toList());
            List<Long> mixes = productIds.stream().filter(r -> dbItemProductIds.contains(r)).collect(Collectors.toList());
            if (oConvertUtils.isNotEmpty(mixes) && mixes.size() > 0) {
                return Result.error("新添加的记录已存在，请重核对后重试！");
            }
        }
        stmReplenishmentItemModel.getDetailList().forEach(r -> {
            r.setReplenishmentId(stmReplenishmentItemModel.getReplenishmentId());
            r.setProductId(productMaps.get(r.getProductSn()));
        });
        stmReplenishmentItemService.saveBatch(stmReplenishmentItemModel.getDetailList());
        return Result.ok("添加门店要货单明细成功！");
    }

    /**
     * 编辑门店要货明细
     *
     * @param stmReplenishmentItem
     * @return
     */
    @AutoLog(value = "门店要货明细-编辑")
    @ApiOperation(value = "门店要货明细-编辑", notes = "门店要货明细-编辑")
    @PutMapping("/editStmReplenishmentItem")
    public Result<?> editStmReplenishmentItem(@RequestBody StmReplenishmentItem stmReplenishmentItem) {
        StmReplenishment stmReplenishment = stmReplenishmentService.getById(stmReplenishmentItem.getReplenishmentId());
        if (oConvertUtils.isEmpty(stmReplenishment)) {
            return Result.error("要货单主表记录为空，请检查后重试！");
        }
        if (stmReplenishment.getStatus() > 3) {
            return Result.error("要货单状态已不可修改商品！");
        }
        stmReplenishmentItemService.updateById(stmReplenishmentItem);
        return Result.ok("编辑门店要货明细成功！");
    }

    /**
     * 通过id删除门店要货明细
     *
     * @param id
     * @return
     */
    @AutoLog(value = "门店要货明细-通过id删除")
    @ApiOperation(value = "门店要货明细-通过id删除", notes = "门店要货明细-通过id删除")
    @DeleteMapping(value = "/deleteStmReplenishmentItem")
    public Result<?> deleteStmReplenishmentItem(@RequestParam(name = "id", required = true) Long id) {
        StmReplenishmentItem stmReplenishmentItem = stmReplenishmentItemService.getById(id);
        StmReplenishment stmReplenishment = stmReplenishmentService.getById(stmReplenishmentItem.getReplenishmentId());
        if (oConvertUtils.isEmpty(stmReplenishment)) {
            return Result.error("要货单主表记录为空，请检查后重试！");
        }
        if (stmReplenishment.getStatus() > 3) {
            return Result.error("要货单状态已不可删除商品！");
        }
        stmReplenishmentItemService.removeById(id);
        return Result.ok("删除门店要货明细成功！");
    }

    /**
     * 批量删除门店要货明细
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "门店要货明细-批量删除")
    @ApiOperation(value = "门店要货明细-批量删除", notes = "门店要货明细-批量删除")
    @DeleteMapping(value = "/deleteBatchStmReplenishmentItem")
    public Result<?> deleteBatchStmReplenishmentItem(@RequestParam(name = "ids", required = true) String ids) {
        if (ids == null || "".equals(ids.trim())) {
            return Result.error("参数不识别！");
        }
        this.stmReplenishmentItemService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.ok("批量删除成功！");

    }


    /**
     * 导出excel
     *
     * @param request
     * @param stmReplenishment
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, StmReplenishment stmReplenishment) {
        // Step.1 组装查询条件
        QueryWrapper<StmReplenishment> queryWrapper = QueryGenerator.initQueryWrapper(stmReplenishment, request.getParameterMap());
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        //要么导出选中的，要么空
        String selections = request.getParameter("selections");
        if (oConvertUtils.isEmpty(selections)) {
            return null;
        }
        List<Long> selectionList = Arrays.asList(selections.split(",")).stream().map(s -> Long.valueOf(s.toString())).collect(Collectors.toList());
        queryWrapper.in("id", selectionList);
        List<StmReplenishment> stmReplenishmentList = stmReplenishmentService.list(queryWrapper);

        StmReplenishment maxReplenishment = stmReplenishmentList.stream().max(Comparator.comparing(StmReplenishment::getCreateTime)).get();
        Date createTime = maxReplenishment.getCreateTime();
        List<StmReplenishment> sList = stmReplenishmentList.stream().filter(r -> oConvertUtils.isNotEmpty(r.getExecTime())).collect(Collectors.toList());
        if (oConvertUtils.isNotEmpty(sList) && sList.size() > 0) {
            StmReplenishment maxExecReplenishment = sList.stream().max(Comparator.comparing(StmReplenishment::getExecTime)).get();
            if (oConvertUtils.isNotEmpty(maxExecReplenishment) && oConvertUtils.isNotEmpty(maxExecReplenishment.getExecTime()) ) {
                createTime = maxExecReplenishment.getExecTime();
            }
        }

        List<StmPrintVO> pageList = stmReplenishmentItemService.selectByIds(selectionList,createTime);

        //Step.2 获取导出数据
        /*List<StmReplenishmentPage> pageList = new ArrayList<StmReplenishmentPage>();
        List<StmReplenishment> stmReplenishmentList = stmReplenishmentService.list(queryWrapper);
        for (StmReplenishment temp : stmReplenishmentList) {
            StmReplenishmentPage vo = new StmReplenishmentPage();
            BeanUtils.copyProperties(temp, vo);
            List<StmReplenishmentItem> stmReplenishmentItemList = stmReplenishmentItemService.selectByMainId(temp.getId());
            vo.setStmReplenishmentItemList(stmReplenishmentItemList);
            pageList.add(vo);
        }*/

        String storeName = "";
        if (oConvertUtils.isNotEmpty(stmReplenishmentList) && stmReplenishmentList.size() > 0) {
            Set<Long> storeIds = stmReplenishmentList.stream().map(r -> r.getStoreId()).collect(Collectors.toSet());
            if (Objects.equals(storeIds.size(),1)) {
                LambdaQueryWrapper<StmStoreInfo> storeQueryWrapper = new LambdaQueryWrapper<>();
                storeQueryWrapper.in(StmStoreInfo::getStoreId,storeIds);
                StmStoreInfo storeInfo = stmStoreInfoService.getOne(storeQueryWrapper,false);
                storeName = storeInfo.getName();
            }
        }

        //Step.3 调用AutoPoi导出Excel
        ModelAndView mv = new ModelAndView(new EntityExcelView());
        mv.addObject(NormalExcelConstants.FILE_NAME, "门店要货单");
        mv.addObject(NormalExcelConstants.CLASS, StmPrintVO.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(storeName+"要货单数据", "导出人:" + sysUser.getRealname(), storeName+"要货单"));
        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
        return mv;
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            try {
                List<StmReplenishmentPage> list = ExcelImportUtil.importExcel(file.getInputStream(), StmReplenishmentPage.class, params);
                for (StmReplenishmentPage page : list) {
                    StmReplenishment po = new StmReplenishment();
                    BeanUtils.copyProperties(page, po);
                    stmReplenishmentService.saveMain(po, page.getStmReplenishmentItemList());
                }
                return Result.ok("文件导入成功！数据行数:" + list.size());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.ok("文件导入失败！");
    }
}
